package pcabst

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/StackExchange/wmi"
	"github.com/shirou/gopsutil/v3/host"
	"github.com/urfave/cli/v2"
	"os"
)

var (
	BuildTime string
	Version   = "1.0.0"
)

func Do() {
	app := &cli.App{
		Name:        "sysInfo",
		Version:     fmt.Sprintf("%s build:%s", Version, BuildTime),
		Usage:       "sys [global options] command [command options] ",
		UsageText:   "指令参考：\n ",
		Description: "获取系统概述信息，部分双操作系统的机器不适合使用该工具",
		Action: func(context *cli.Context) error {
			var (
				d   SystemAbstract
				err error
				bs  []byte
			)
			d, err = GetInfo()
			if err != nil {
				return cli.Exit(fmt.Sprintf("获取系统概述信息时发生错误:%s", err), 1)
			}
			bs, err = json.Marshal(d)
			fmt.Println(string(bs))
			return nil
		},
	}
	if err := app.Run(os.Args); err != nil {
		fmt.Printf("命令行调用错误：%s ，请查看帮助文档", err.Error())
	}
}

// Hostname、Name、CSName 三者是否重复？KernelVersion、BuildNumber、Version 三者是否重复？
type SystemAbstract struct {
	OS            string
	Hostname      string
	KernelArch    string
	KernelVersion string
	SYSAbstract
	SYSOperating
}

type SYSAbstract struct {
	Domain                    string // eg:WORKGROUP, 域
	Manufacturer              string // eg:HASEE Computer ,制造商
	Model                     string // eg:H310CM ,型号
	Name                      string // eg：hcy，名称
	NumberOfLogicalProcessors uint32 // eg:6, 逻辑处理器数量
	NumberOfProcessors        uint32 // eg:1 ,物理处理器数量
	PartOfDomain              bool   // eg:false, 计算机是否入域
	SystemType                string // eg；x64-based PC ，系统类型
	UserName                  string // eg:rock , 当前登陆的用户，注意，如果以服务形式启动，可能获取不到这个值。
}
type SYSOperating struct {
	BuildNumber    string // eg : 19043 .操作系统的构建号,它比产品发布版本号更精确的版本信息。
	Caption        string // eg:Microsoft Windows 10 专业版 , 系统标题
	CSName         string // eg:HCY , 计算机名
	Description    string // eg:hechongyang ,系统描述
	Distributed    bool   // eg：false ，该计算机是否为一个分布式系统的节点
	InstallDate    string // eg: 20210207150436.000000+480 ,// 操作系统安装时间
	LocalDateTime  string // eg:20210929164244.818000+480 ,// 操作系统最后一次的启动时间
	OSArchitecture string // eg: 64位 ，操作系统位数
	Primary        bool   // eg:true ,当前操作系统是否位主系统，部分电脑可能存在双操作系统
	SerialNumber   string // eg:00330-80191-48344-AA161, 操作系统产品序列号。
	SystemDrive    string // eg:c； ，系统盘卷标
	Version        string // eg:10.0.19043 ,系统版本号
}

func GetInfo() (data SystemAbstract, err error) {
	var (
		s1 []SYSAbstract
		s2 []SYSOperating
		h  *host.InfoStat
	)
	err = wmi.Query("select * from Win32_ComputerSystem", &s1)
	if err != nil {
		return data, err
	}
	err = wmi.Query("select * from Win32_OperatingSystem", &s2)
	if err != nil {
		return data, err
	}
	if len(s1) != len(s2) && len(s1) != 1 {
		return data, errors.New("需要适配的操作系统，请联系管理员！")
	}
	data.SYSAbstract = s1[0]
	data.SYSOperating = s2[0]
	h, err = host.Info()
	if err != nil {
		return data, errors.New(fmt.Sprintf("需要适配的操作系统，请联系管理员！err：%s", err))
	}
	data.OS = h.OS
	data.Hostname = h.Hostname
	data.KernelArch = h.KernelArch
	data.KernelVersion = h.KernelVersion
	return data, nil
}
